<?php
/**
 * 控制器基类
 */
declare(strict_types=1);

namespace Libraries\Bases;

use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Coroutine;
use Libraries\Context;
use voku\helper\AntiXSS;

abstract class ControllerBase
{
    /* ------------------------------------------------------------------------
     * 此配置用于跳过HOOK
     * “*” => 不参与任何HOOK
     * “['auth' => '*']” => 不参与auth的Hook
     * “['auth' => ['login', 'index']]” => login和index方法不参与auth的Hook
     ----------------------------------------------------------------------- */
    public $skipHooks = []; // 默认：不跳过任何Hook
    public $arrHookData = []; // 用于存放Hook设置的数据
    public $blnOutputEnd = false; // 页面是否输出结束
    public $arrSession = []; // SESSION数据
    public $intFd = -1; // 连接标识
    public $strRemoteIp = ''; // 客户端IP
    // public $strPost = ''; // 原始的 POST 包体
    public $arrPost = []; // POST数据
    public $arrGet = []; // GET数据
    public $arrCookie = []; // COOKIE数据
    public $arrFiles = []; // 上传文件
    public $arrTmpFiles = []; // 上传文件
    public $arrServer = []; // $_SERVER
    public $arrHeader = []; // $_HEADER
    public $strExt = ''; // html/php/js/json/png
    public $strRequestMethod = 'GET'; // GET/POST
    public $blnIsAjax = false; // 是否为Ajax请求
    public $objResponse = null; // 内容输出的实例
    protected $objRequest = null; // 请求的实例
    protected $blnStartSess = false; // 默认不开启Session
    protected $strSessId = ''; // SESSION_ID
    protected $strSessCookieName = 'MY_SESSION_ID'; // SessionId在Cookie中的名称

    /**
     * ControllerBase constructor.
     *
     * @param Request $objRequest
     * @param Response $objResponse
     */
    public function __construct(Request $objRequest, Response $objResponse)
    {
        /* init */
        $this->intFd = $objRequest->fd;
        $arrPost = $objRequest->post ?? [];
        $arrGet = $objRequest->get ?? [];
        $this->arrCookie = $objRequest->cookie ?? [];
        $this->arrServer = $objRequest->server ?? [];
        $this->arrFiles = $objRequest->files ?? [];
        $arrHeader = $objRequest->header ?? [];
        $this->arrTmpFiles = $objRequest->tmpfiles ?? [];
        $this->strRequestMethod = $this->arrServer['request_method'];
        // $this->strPost = $objRequest->getContent();
        $this->objRequest = $objRequest;
        $this->objResponse = $objResponse;
        /* XSS Clean */
        $objXssCleaner = new AntiXSS();
        $arrPost && $this->arrPost = $objXssCleaner->xss_clean($arrPost);
        $arrGet && $this->arrGet = $objXssCleaner->xss_clean($arrGet);
        $arrHeader && $this->arrHeader = $objXssCleaner->xss_clean($arrHeader);
        $this->strRemoteIp = ($this->arrHeader['x-real-ip'] ?? ($this->arrServer['remote_addr'] ?? ''));
        /* is ajax request? */
        $strTemp = ($this->arrHeader['x-requested-with'] ?? '');
        $this->blnIsAjax = (strtolower($strTemp) === 'xmlhttprequest');
        unset($objXssCleaner, $arrGet, $arrPost, $arrHeader, $strTemp);
        /* session start */
        if ($this->blnStartSess) {
            $this->strSessId = $this->arrCookie[$this->strSessCookieName] ?? '';
            if (!is_string($this->strSessId) || !strlen($this->strSessId)) {
                $this->strSessId = session_create_id();
                $this->objResponse->cookie(
                    $this->strSessCookieName,
                    $this->strSessId,
                    (8640000 + time()),
                    '/',
                    '',
                    false,
                    true
                ); // 100天有效期
            } else {
                $this->arrSession = Context::get($this->strSessId, 'session');
                is_array($this->arrSession) || $this->arrSession = [];
            }
            /* save session */
            Coroutine::defer(function () {
                is_array($this->arrSession) || $this->arrSession = [];
                Context::set($this->strSessId, 'session', $this->arrSession);
            });
        }
    }
}
